package top.hymsk.ecommerce.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.hymsk.ecommerce.dao.mapper.OrderMapper;
import top.hymsk.ecommerce.pojo.DO.OrderBuyerOverviewDO;
import top.hymsk.ecommerce.pojo.DO.OrderGoodsListDO;
import top.hymsk.ecommerce.pojo.DO.OrderOverviewDO;
import top.hymsk.ecommerce.pojo.DTO.OrderBuyerOverviewListDTO;
import top.hymsk.ecommerce.pojo.DTO.OrderDetailDTO;
import top.hymsk.ecommerce.pojo.DTO.OrderSellerOverviewListDTO;
import top.hymsk.ecommerce.pojo.DTO.PlaceProductDTO;
import top.hymsk.ecommerce.pojo.PO.mysql.OrderPO;
import top.hymsk.ecommerce.pojo.response.GeneralResponse;
import top.hymsk.ecommerce.pojo.status.OrderGoodStatusCode;
import top.hymsk.ecommerce.pojo.status.OrderStatusCode;
import top.hymsk.ecommerce.pojo.status.ResponseStatusCode;
import top.hymsk.ecommerce.service.OrderService;
import top.hymsk.ecommerce.utils.TimeUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 花于陌上开
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderMapper orderMapper;

    /*买家模块*/

    /**
     * 获取订单列表
     * (基本完成)
     *
     * @param userId 用户id
     * @return 响应信息
     */
    @Override
    public GeneralResponse getOrderListByBuyer(Integer userId, Integer page) {
        Integer begin = page * 10;
        //查询所有订单信息
        List<OrderBuyerOverviewDO> orderListByUserId = orderMapper.getOrderListByUserId(userId, begin);
        //需要解析时间，总条数
        Integer number = orderMapper.getOrderNumberByUserId(userId);
        OrderBuyerOverviewListDTO orderList = new OrderBuyerOverviewListDTO(orderListByUserId, number);
        return GeneralResponse.success(orderList);
    }

    /**
     * 创建订单
     * (基本完成)
     *
     * @param userId           用户id
     * @param placeProductList 订单商品及数量列表
     * @return 响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public GeneralResponse place(Integer userId, List<PlaceProductDTO> placeProductList) {
        //插入订单信息(使用事务)->订单状态进入 OrderStatusCode.NON_PAYMENT (未支付)
        List<Integer> productIdList = placeProductList.stream().map(PlaceProductDTO::getProductId).collect(Collectors.toList());
        List<Integer> productNumberList = placeProductList.stream().map(PlaceProductDTO::getNumber).collect(Collectors.toList());
        placeProductList = orderMapper.analysisPlaceProduct(productIdList);
        OrderGoodsListDO orderGoodsList = new OrderGoodsListDO(placeProductList, productNumberList);
        OrderPO order = new OrderPO(null, userId, System.currentTimeMillis() / 1000, orderGoodsList.getAmount(), OrderStatusCode.NON_PAYMENT.getStatusCode());
        orderMapper.insertNewOrder(order);
        orderMapper.insertNewOrderGoods(order.getOrderId(), placeProductList, OrderGoodStatusCode.NON_PAYMENT.getStatusCode());
        return GeneralResponse.success();
    }

    /**
     * 支付
     * (基本完成)
     *
     * @param userId  用户id
     * @param orderId 订单id
     * @return 响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public GeneralResponse payment(Integer userId, Integer orderId) {
        // 查询订单状态
        OrderStatusCode orderStatusCode = tranOrderStatusCode(orderMapper.getOrderStatus(orderId));
        //查询订单状态是否为 OrderStatusCode.NON_PAYMENT (未支付)
        if (orderStatusCode.equals(OrderStatusCode.NON_PAYMENT)) {
            //修改订单支付状态 ->订单状态进入 OrderStatusCode.HAS_PAYMENT (已支付)
            orderMapper.updateOrderStatusByOrderId(orderId, OrderStatusCode.HAS_PAYMENT.getStatusCode());
            orderMapper.updateOrderGoodStatusByOrderId(orderId, OrderGoodStatusCode.WAIT_DELIVER.getStatusCode());
            return GeneralResponse.success();
        }
        return GeneralResponse.fail(ResponseStatusCode.STATUS_ERROR);
    }

    /**
     * 查看订单状态(买家)
     * (基本完成)
     *
     * @param userId  用户id
     * @param orderId 订单id
     * @return 响应信息
     */
    @Override
    public GeneralResponse getStatusByBuyer(Integer userId, Integer orderId) {
        // 查询订单状态
        OrderOverviewDO orderByBuyer = orderMapper.getOrderByBuyer(userId, orderId);
        if (orderByBuyer == null) {
            return GeneralResponse.fail(ResponseStatusCode.PERMISSION_ERROR);
        }
        OrderDetailDTO order = new OrderDetailDTO(orderByBuyer);
        return GeneralResponse.success(order);
    }

    /**
     * 取消订单(只有在未支付能取消订单)
     * (基本完成)
     *
     * @param userId  用户id
     * @param orderId 订单id
     * @return 响应信息
     */
    @Override
    public GeneralResponse cancel(Integer userId, Integer orderId) {
        // 查询订单状态，订单为未支付状态才能取消
        if (tranOrderStatusCode(orderMapper.getOrderStatus(orderId)).equals(OrderStatusCode.NON_PAYMENT)) {
            orderMapper.updateOrderStatusByOrderId(orderId, OrderStatusCode.HAS_CANCEL.getStatusCode());
            return GeneralResponse.success();
        }
        return GeneralResponse.fail(ResponseStatusCode.STATUS_ERROR);
    }

    /**
     * 订单商品退款(只有订单商品为待发货才能退款)
     * (基本完成)
     *
     * @param userId    用户id
     * @param orderId   订单id
     * @param productId 商品id
     * @return 响应信息
     */
    @Override
    public GeneralResponse refund(Integer userId, Integer orderId, Integer productId) {
        // 查询订单商品状态，订单商品为待发货才能退款
        if (tranGoodStatusCode(orderMapper.getOrderGoodStatus(orderId, productId)).equals(OrderGoodStatusCode.WAIT_DELIVER)) {
            orderMapper.updateOrderGoodStatusByOrderAndProductId(orderId, productId, OrderGoodStatusCode.REFUNDED.getStatusCode());
            return GeneralResponse.success();
        }
        return GeneralResponse.fail(ResponseStatusCode.STATUS_ERROR);
    }

    /**
     * 收货(订单全部发货才能收货)
     * (基本完成)
     *
     * @param userId  用户id
     * @param orderId 订单id
     * @return 响应信息
     */
    @Override
    public GeneralResponse receive(Integer userId, Integer orderId) {
        // 查询订单商品状态，订单商品为订单全部发货/退款才能收货
        OrderDetailDTO order = new OrderDetailDTO(orderMapper.getOrderByBuyer(userId, orderId));
        if (tranOrderStatusCode(order.getStatus()).equals(OrderStatusCode.HAS_PAYMENT)) {
            boolean isAllDeliver = true;
            for (OrderDetailDTO.Product product : order.getProductList()) {
                if (!(tranGoodStatusCode(product.getStatus()).equals(OrderGoodStatusCode.WAIT_DECEIVING) || tranGoodStatusCode(product.getStatus()).equals(OrderGoodStatusCode.REFUNDED))) {
                    isAllDeliver = false;
                    break;
                }
            }
            if (isAllDeliver) {
                orderMapper.changeOrderGoodStatusByOrderId(orderId, OrderGoodStatusCode.WAIT_DECEIVING.getStatusCode(), OrderGoodStatusCode.AWAITING_REMARK.getStatusCode());
                return GeneralResponse.success();
            }
        }
        return GeneralResponse.fail(ResponseStatusCode.STATUS_ERROR);
    }


    /**
     * 商品评论
     * (基本完成)
     *
     * @param userId    用户id
     * @param orderId   订单id
     * @param productId 商品id
     * @param remark    评论
     * @param star      评分
     * @return 响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public GeneralResponse remark(Integer userId, Integer orderId, Integer productId, String remark, Double star) {
        //查询订单商品状态是否为 OrderGoodStatusCode.AWAITING_REMARK
        if (tranGoodStatusCode(orderMapper.getOrderGoodStatus(orderId, productId)).equals(OrderGoodStatusCode.AWAITING_REMARK)) {
            orderMapper.updateOrderStatusByOrderId(orderId, OrderStatusCode.HAS_CANCEL.getStatusCode());
            //修改订单商品状态为 OrderGoodStatusCode.REVIEWED (已评论)
            orderMapper.updateOrderGoodStatusByOrderAndProductId(orderId, productId, OrderGoodStatusCode.REVIEWED.getStatusCode());
            //添加评论信息
            if (!orderMapper.insertNewComment(userId, productId, orderId, TimeUtils.getTime(), star, remark)) {
                throw new RuntimeException("评论未成功");
            }

            return GeneralResponse.success();
        }
        // 查询订单状态
        OrderOverviewDO orderByBuyer = orderMapper.getOrderByBuyer(userId, orderId);
        if (orderByBuyer == null) {
            return GeneralResponse.fail(ResponseStatusCode.PERMISSION_ERROR);
        }
        return GeneralResponse.fail(ResponseStatusCode.STATUS_ERROR);
    }

    /*卖家模块*/

    /**
     * 获取订单列表
     * (基本完成)
     *
     * @param storeId 店铺id
     * @return 响应信息
     */
    @Override
    public GeneralResponse getOrderListBySeller(Integer storeId, Integer page) {
        Integer begin = page * 10;
        //查询所有订单信息
        List<OrderOverviewDO> orderList = orderMapper.getOrderListByStoreId(storeId, begin);
        //需要解析时间，总数量
        Integer number = orderMapper.getOrderNumberByStoreId(storeId);
        return GeneralResponse.success(new OrderSellerOverviewListDTO(orderList, number));
    }


    /**
     * 查看订单状态(卖家)
     * (基本完成)
     *
     * @param storeId 店铺id
     * @param orderId 订单id
     * @return 响应信息
     */
    @Override
    public GeneralResponse getStatusBySeller(Integer storeId, Integer orderId) {
        //查询订单状态
        OrderOverviewDO orderBySeller = orderMapper.getOrderBySeller(storeId, orderId);
        if (orderBySeller == null) {
            return GeneralResponse.fail(ResponseStatusCode.PERMISSION_ERROR);
        }
        OrderDetailDTO order = new OrderDetailDTO(orderBySeller);
        return GeneralResponse.success(order);
    }

    /**
     * 发货
     * (基本完成)
     *
     * @param storeId       店铺id
     * @param orderId       订单id
     * @param courierNumber 物流编号
     * @return 响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public GeneralResponse deliver(Integer storeId, Integer orderId, String courierNumber) {
        //查询订单状态
        OrderDetailDTO order = new OrderDetailDTO(orderMapper.getOrderBySeller(storeId, orderId));
        if (tranOrderStatusCode(order.getStatus()).equals(OrderStatusCode.HAS_PAYMENT)) {
            boolean isNotAllRefund = false;
            List<Integer> waitDeceivingId = new ArrayList<>();
            for (OrderDetailDTO.Product product : order.getProductList()) {
                Integer status = product.getStatus();
                if (tranGoodStatusCode(status).equals(OrderGoodStatusCode.WAIT_DELIVER)) {
                    isNotAllRefund = true;
                }
                if (tranGoodStatusCode(status).equals(OrderGoodStatusCode.WAIT_DELIVER)) {
                    waitDeceivingId.add(product.getProductId());
                }
            }
            System.out.println(waitDeceivingId);
            if (isNotAllRefund) {
                orderMapper.changeOrderGoodStatusByOrderIdAndStoreId(orderId, storeId, OrderGoodStatusCode.WAIT_DELIVER.getStatusCode(), OrderGoodStatusCode.WAIT_DECEIVING.getStatusCode());
                //添加物流
                orderMapper.insertNewExpress(orderId, waitDeceivingId, courierNumber);
                return GeneralResponse.success();
            }
        }
        return GeneralResponse.fail(ResponseStatusCode.STATUS_ERROR);
    }

    protected OrderStatusCode tranOrderStatusCode(Integer status) {
        if (status == null) {
            return OrderStatusCode.ORDER_NOT_EXIST;
        } else if (status == 0) {
            return OrderStatusCode.ORDER_NOT_EXIST;
        } else if (status == 1) {
            return OrderStatusCode.NON_PAYMENT;
        } else if (status == 2) {
            return OrderStatusCode.HAS_PAYMENT;
        } else {
            return OrderStatusCode.STATUS_ERROR;
        }
    }

    protected OrderGoodStatusCode tranGoodStatusCode(Integer status) {
        if (status == null) {
            return OrderGoodStatusCode.ORDER_GOOD_NOT_EXIST;
        } else if (status == 0) {
            return OrderGoodStatusCode.NON_PAYMENT;
        } else if (status == 1) {
            return OrderGoodStatusCode.WAIT_DELIVER;
        } else if (status == 2) {
            return OrderGoodStatusCode.WAIT_DECEIVING;
        } else if (status == 3) {
            return OrderGoodStatusCode.AWAITING_REMARK;
        } else if (status == 4) {
            return OrderGoodStatusCode.REVIEWED;
        } else if (status == 5) {
            return OrderGoodStatusCode.REFUNDED;
        } else {
            return OrderGoodStatusCode.STATUS_ERROR;
        }
    }
}
